package com.uade.empresasdistribuidas.model;

import java.sql.Date;
import java.util.ArrayList;
import java.util.Calendar;

import com.uade.empresasdistribuidas.connection.HibernateUtil;
import com.uade.empresasdistribuidas.dao.PedidoDAO;
import com.uade.empresasdistribuidas.dao.PedidoDAOImpl;
import com.uade.empresasdistribuidas.entities.CargaDTO;
import com.uade.empresasdistribuidas.entities.ClienteDTO;
import com.uade.empresasdistribuidas.entities.DireccionDTO;
import com.uade.empresasdistribuidas.entities.EmpresaDTO;
import com.uade.empresasdistribuidas.entities.EnvioDTO;
import com.uade.empresasdistribuidas.entities.FacturaDTO;
import com.uade.empresasdistribuidas.entities.ParticularDTO;
import com.uade.empresasdistribuidas.entities.PedidoDTO;
import com.uade.empresasdistribuidas.entities.PedidoLocalDTO;
import com.uade.empresasdistribuidas.entities.ReciboDTO;
import com.uade.empresasdistribuidas.entities.RemitoDTO;
import com.uade.empresasdistribuidas.exception.PedidoNotFoundException;
import com.uade.empresasdistribuidas.model.interfaz.Estado;
import com.uade.empresasdistribuidas.view.IniciarPedidoView;

public abstract class Pedido {

	private static PedidoDAO pedidoDAO;
	protected PedidoDTO pedido;
	protected Estado estado;
	protected Cliente cliente;



	public Pedido(PedidoDTO pedido2) {
		this.pedido = pedido2;
		asignarEstado(pedido.getEstado());
	}
	
	public Pedido(IniciarPedidoView iniciarPedidoView) {
		fillPedidoData(iniciarPedidoView);
		fillDireccionData(iniciarPedidoView);
		fillClienteData(iniciarPedidoView);
	}
	
	
	public Pedido(Integer pedidoId, String dniDestinatario) throws PedidoNotFoundException {
		this.pedido=getPedidoDAO().findPedidoARetirar(pedidoId,dniDestinatario);
		asignarEstado(pedido.getEstado());
		if(pedido==null){
			throw  new PedidoNotFoundException("Pedido no encontrado en ese Estado");
		}
	}


	private void fillClienteData(IniciarPedidoView iniciarPedidoView) {
		ClienteDTO cliente = null;
		if (iniciarPedidoView.isEsEmpresa()) {
			cliente = new ParticularDTO();
		} else {
			cliente = new EmpresaDTO();
		}
		cliente.setNumeroCliente(iniciarPedidoView.getIdCliente());
		pedido.setCliente(cliente);
	}

	private void fillDireccionData(IniciarPedidoView iniciarPedidoView) {
		DireccionDTO direccion = new DireccionDTO();
		direccion.setCalle(iniciarPedidoView.getCalle());
		direccion.setCodigoPostal(iniciarPedidoView.getCodigoPostal());
		direccion.setLocalidad(iniciarPedidoView.getLocalidad());
		direccion.setPiso(iniciarPedidoView.getPiso());
		direccion.setDepartamento(iniciarPedidoView.getDepartamento());
		direccion.setPais(iniciarPedidoView.getPais());
		direccion.setLocalidad(iniciarPedidoView.getLocalidad());
		direccion.setProvincia(iniciarPedidoView.getProvincia());
		direccion.setNumero(iniciarPedidoView.getNumero());
		pedido.setDireccion(direccion);
		
	}

	private void fillPedidoData(IniciarPedidoView iniciarPedidoView) {
		pedido = new PedidoLocalDTO();
		pedido.setFechaMaxima(Date.valueOf(iniciarPedidoView.getFechaMaximaLlegada()));
		pedido.setNombreDestinatario(iniciarPedidoView.getNombreDestinatario());
		pedido.setManifiesto(iniciarPedidoView.getManifiesto());
		pedido.setDocumentoDestinatario(iniciarPedidoView.getDniDestinatario());
		pedido.setCargas(new ArrayList<CargaDTO>());
		pedido.setEstado(EnDeposito.EN_DEPOSITO);
		
	}

	public void cambiarEstado(){
		estado.doAction(this);
	}

	private void asignarEstado(String estado) {
		if (Estado.EN_DEPOSITO.equals(estado)) {
			this.estado=new EnDeposito();
		} else if (Estado.EN_TRANSITO.equals(estado)) {
			this.estado=new EnTransito();
		} else if (Estado.PENDIENTE_ENVIO_PUERTA.equals(estado)) {
			this.estado=new PendienteEnvioPuerta();
		} else if (Estado.ENTREGADO.equals(estado)) {
			this.estado=new Entregado();
		} else if (Estado.PENDIENTE_RETIRO.equals(estado)) {
			this.estado=new PendienteRetiro();
		} else if (Estado.RETIRO_MERCADERIAS.equals(estado)) {
			this.estado=new RetiroMercaderias();
		}
	}


	abstract public void persistirPedido();

	public PedidoDTO getPedido() {
		return pedido;
	}

	public void setPedido(PedidoDTO pedido) {
		this.pedido = pedido;
	}

	public Estado getEstado() {
		return estado;
	}

	public void setEstado(Estado estado) {
		this.estado = estado;
	}

	public Float getPeso() {

		return pedido.obtenerPesoPedido();
	}

	public boolean esRefrigerado() {
		return pedido.esRefrigerado();
	}

	public void asignarEnvio(EnvioDTO envio) {
		pedido.setEnvio(envio);
	}

	
	public static PedidoDAO getPedidoDAO() {
		if (pedidoDAO == null) {
			pedidoDAO = new PedidoDAOImpl();
			pedidoDAO.setSession((HibernateUtil.getSession()));
		}
		return pedidoDAO;

	}

	public Date getFechaMaxima() {
		return pedido.getFechaMaxima();
	}

	public abstract Float obtenerCostoEnvio();

	protected FacturaDTO crearFactura(Float costoViaje, Float costo) {
		FacturaDTO factura = new FacturaDTO();
		factura.setFecha(new Date(Calendar.getInstance().getTimeInMillis()));
		factura.setDescripcion("Pedido de transporte de mercaderias");
		factura.setFormaDePago("Tarjeta, c/c o efectivo");
		factura.setMonto(costoViaje + costo);
		factura.setPedido(pedido);
		factura.setCliente(pedido.getCliente());
		return factura;
	}

	protected ReciboDTO crearRecibo() {
		ReciboDTO recibo = new ReciboDTO();
		recibo.setFecha(new Date(Calendar.getInstance().getTimeInMillis()));
		recibo.setDescripcion("Se recibieron conformemente los objetos a ser enviados");
		recibo.setPedido(pedido);
		return recibo;
	}

	public void actualizarPedido() {
		getPedidoDAO().makePersistent(pedido);
		
	}

	public void addCarga(CargaDTO carga) {
		pedido.addCarga(carga);
		carga.setPedido(this.getPedido());
		
	}

	public RemitoDTO obtenerRemitoExterno() {
		
		return pedido.obtenerRemitoExterno();
	}
	

	
	

}
